package com.wontube.smr.bo.sites.analizers;

import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import com.wontube.client.extension.utils.net.URLUtils;
import com.wontube.core.pub.ServerContext;
import com.wontube.smr.bo.sites.youtube.IYouTubeService;
import com.wontube.smr.bo.sites.youtube.YouTubeFactory;
import com.wontube.smr.client.model.vo.VideoFile;
import com.wontube.smr.client.model.vo.VideoFiles;
import com.wontube.smr.model.vo.youtube.YouTubeVideoFile;

/**
 * @author yuechao
 * 
 */
public class YouTubeVideoAnalizer implements IVideoAnalizer {
	//  我们想要的视频格式，以空间换时间
	//  {L"37", L"1920 x 1080", L"1080p HD", L"MP4", L"?"} 
	//	{L"22", L"1280 x 720", L"720p HD", L"MP4", L"2"},
	//	{L"35", L"854 x 480", L"480p", L"FLV", L"4"},
	//
	//	{L"18", L"640 x 360", L"360p", L"MP4", L"6"},
	//	{L"34", L"640 x 360", L"360p", L"FLV", L"7"},
	//
	//	{L"5", L"320 x 240", L"240p", L"FLV", L"10"},
	private static final HashMap<Integer, Boolean> mapVideo = new HashMap<Integer, Boolean>();
	
	static {
		mapVideo.put(37, Boolean.TRUE);
		mapVideo.put(22, Boolean.TRUE);
		mapVideo.put(35, Boolean.TRUE);
		mapVideo.put(18, Boolean.TRUE);
		mapVideo.put(34, Boolean.TRUE);
		mapVideo.put(5, Boolean.TRUE);
	}
	
	/*
	 * @see smr.bo.IVideoAnalizer#getPriority()
	 */
	@Override
	public int getPriority() {
		return 0;
	}

	/*
	 * @see smr.bo.IVideoAnalizer#getSiteName()
	 */
	@Override
	public String getSiteName() {
		return "youtube";
	}

	/*
	 * @see smr.bo.IVideoAnalizer#canProcess(java.lang.String)
	 */
	@Override
	public boolean canProcess(String url) {
		return !"".equals(getVideoId(url));
	}

	/*
	 * @see smr.bo.IVideoAnalizer#getAllVideos(java.lang.String)
	 */
	@Override
	public boolean getAllVideos(ServerContext context, VideoFiles videoFiles, String url) {
		String videoId = getVideoId(url);
		if ("".equals(videoId)) {
			context.error("Please Enter the Valid YouTube URL.");
			return false;
		}

		String pageUrl = "http://www.youtube.com/watch?v=" + videoId;
		HashMap<Integer, VideoFile> map = new HashMap<Integer, VideoFile>();
		if (this.analyzeVideoUrls(videoFiles, pageUrl)) {
			// 过滤
			for (int i = 0; i < videoFiles.getVideos().size(); i++) {
				VideoFile videoFile = videoFiles.getVideos().get(i);
				
				if (mapVideo.containsKey(videoFile.getFormatCode())) {
					map.put(videoFile.getFormatCode(), videoFile);
				}
			}
			
			// 看看是否同时存在  360p 的 mp4 与 flv
			if (map.containsKey(18) && map.containsKey(34)) {
				map.remove(34);
			}
			
			// 返回
			videoFiles.getVideos().clear();
			videoFiles.getVideos().addAll(map.values());
			
			// 排序
			Collections.sort(videoFiles.getVideos(), new Comparator<VideoFile>() {
				@Override
				public int compare(VideoFile o1, VideoFile o2) {
					if (o1.getFileExt().equalsIgnoreCase(o2.getFileExt())) {
						return o2.getFormatCode() - o1.getFormatCode();
					}
					
					if (".mp4".equalsIgnoreCase(o1.getFileExt())) {
						return -1;
					}
					
					return 1;
				}			
			});
		}
		
		return false;
	}

	/**
	 * @param videoFiles
	 * @param pageUrl  已经正规化的url
	 * @return
	 */
	public boolean analyzeVideoUrls(VideoFiles videoFiles, String pageUrl) {
		// 分析
		IYouTubeService service = YouTubeFactory.create();
		if (!service.obtain(pageUrl)) {
			throw new RuntimeException(service.getErrMsg());
		}
		
		videoFiles.setPageUrl(service.getPageUrl());
		videoFiles.setTitle(service.getVideoTitle());
		videoFiles.setCookie(service.getCookie());

		for (YouTubeVideoFile file : service.getFormats()) {
			VideoFile videoFile = new VideoFile();
			videoFile.setId(UUID.randomUUID().toString());
			videoFile.setFileExt(file.getFileExt());
			videoFile.setFormatCode(file.getFormatCode());
			videoFile.setQuality(file.getVideoQuality());
			videoFile.setSize(file.getVideoSize());
			videoFile.setUrl(file.getVideoUrl());
			videoFile.setVideoType(file.getVideoFormat().toString());
	
			videoFiles.getVideos().add(videoFile);
		}

		return true;
	}

	public static String getVideoId(String url) {
		if (url.startsWith("https://")) {
			url = "http://" + url.substring(8);
		} else if (!url.startsWith("http://")) {
			url = "http://" + url;
		}

		url = url.replace("youtu.be/", "youtube.com/watch?v=");
		url = url.replace("http://youtube.com", "http://www.youtube.com");
		url = url.replace("http://m.youtube.com/", "http://www.youtube.com/");
		
		if (!url.startsWith("http://www.youtube.com")) {
			return "";
		}

		//url = url.replace("www.youtube.com", "youtube.com");
		if (url.startsWith("http://www.youtube.com/v/")) {
			url = url.replace("www.youtube.com/v/", "www.youtube.com/watch?v=");
		} else if (url.startsWith("http://www.youtube.com/watch#")) {
			url = url.replace("www.youtube.com/watch#", "www.youtube.com/watch?");
		}

		String main = "http://www.youtube.com/watch";
		if (!url.startsWith(main)) {
			return "";
		}

		int index = url.indexOf('?');
		if (index >= 0) {
			String query = url.substring(index + 1);
			Map<String, String> map = URLUtils.parseQueryString(query);
			if (map.containsKey("v")) {
				return map.get("v");
			} 
		}
		
		return "";
	}
}
